今天要來跟大家分享的是always block的行為,首先先跟大家說一下一些注意的事項,寫在always裡面的變數必須是宣告成reg的形式,這昨天有提醒過,接下來就是同一個變數只能在同一個always block出現,
例如:
reg[7:0]counter;
always@(posedge clk)begin
if(reset) counter <= 0;
end
always@(posedge clk)begin
if(c1 == 1) counter <= counter + 1;
end
像上面的例子就會有問題,原因就是假設reset 跟 c1 同時成立,那counter該歸零還是做累加的動作呢,因為他們並沒有優先權的順序,所以會有問題,所以應該把它改為:
always@(posedge clk)begin
if(reset) counter <= 0;
else if(c1 == 1) counter <= counter + 1;
end
如果你這樣寫也會有相似的問題:
always@(posedge clk)begin
if(reset) counter <= 0;
if(c1 == 1) counter <= counter + 1;
end
以上這些寫法大家可要注意一下,把自己想像成電路合成器,如果這樣寫的話我要的電路產生的出來嘛,電路跟我想的功能會是一樣的嗎.
再來是always觸發條件,大家可以來看一下兩種行為模式
always@(posedge clk) 跟 always@(a or b)
兩個的差異是前者是會依據時脈訊號(clock)做變化,意思是當clock上升的瞬間去做always block內的動作,稱為循序邏輯電路(Sequential Logic) ,而後者是當a或者是b有變化時,才會去做always block裡的變化,跟clock無關,稱為組合邏輯電路(Combinational Logic)以下舉一個簡單的例子及對照波形給大家看:
module always_behavior(
input clk,
input [7:0]a,
input [7:0]b,
output reg[7:0]c,
output reg[7:0]d
);
always@(posedge clk)begin
c <= a + b;
end
always@(a or b)begin
d = a + b;
end
endmodule
上面的程式跑模擬之後產生的波形圖如下,在黃線順間我給兩個input值分別為4跟7,我們來觀察一下輸出的變化.
由波形圖可知道,在黃線部分output d的結果會根據a b的值改變而馬上改變,這就是組合邏輯電路,假設敘述從always@(a or b)begin 改成 always@(a)begin,
那這樣的話,即使b改變,結果d的值就不改變,順便提一下:
always@(a or b) 寫法等同於 always@(a , b),如果不想寫這麼多的話,也可以直接寫always@(*),意思就是當裡面有任何訊號線改變是就會執行always block的行為.
再來看output c的值,他並沒有像d一樣馬上改變,而是等到時脈上升的瞬間做改變,這就是循序邏輯電路,那大家有個概念之後,等語法分享完會再回來討論兩者之間的應用.